﻿using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Kingdee.BOS.Web;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RK.SerivesPlugin.Ronma
{
    [Description("操作前-润马采购订单提交时回写库存数量等。。"), HotUpdate]
    public class DzBeforeExecuteOperationTransaction : AbstractOperationServicePlugIn
    {
        public override void BeginOperationTransaction(BeginOperationTransactionArgs e)
        {
            base.BeginOperationTransaction(e);
            var formId = this.BusinessInfo.GetForm().Id;
            var operationNumber = this.FormOperation.Operation;
            var obj = e.DataEntitys.FirstOrDefault();
            var id = Convert.ToInt32(obj["Id"]);
            var maiOrg = obj["PurchaseOrgId"] as DynamicObject;
            int maiOrgId = maiOrg == null ? 0 : Convert.ToInt32(maiOrg["Id"]);
            //采购订单
            if (formId == "PUR_PurchaseOrder")
            {
                if (operationNumber == "Submit")
                {
                    ReSaveObj(id, this.OperationResult, maiOrgId);
                }
            }
        }
        //public override void BeforeExecuteOperationTransaction(BeforeExecuteOperationTransaction e)
        //{
        //    base.BeforeExecuteOperationTransaction(e);
        //    var formId = this.BusinessInfo.GetForm().Id;
        //    var operationNumber = this.FormOperation.Operation;
        //    var obj = e.SelectedRows.Select(x => x.DataEntity).FirstOrDefault();
        //    var id = Convert.ToInt32(obj["Id"]);
        //    var maiOrg = obj["PurchaseOrgId"] as DynamicObject;
        //    int maiOrgId = maiOrg == null ? 0 : Convert.ToInt32(maiOrg["Id"]);
        //    //采购订单
        //    if (formId == "PUR_PurchaseOrder")
        //    {
        //        if (operationNumber == "Submit")
        //        {
        //            ReSaveObj(id, this.OperationResult, maiOrgId);
        //            //List<string> sqlArray = new List<string>();
        //            //var eRows = obj["POOrderEntry"] as DynamicObjectCollection;
        //            //foreach (var row in eRows)
        //            //{
        //            //    var eId = Convert.ToInt32(row["Id"]);
        //            //    var mat = row["MaterialId"] as DynamicObject;
        //            //    var matNumber = mat["Number"].ToString();
        //            //    var auxPropId = row["AuxPropId"] as DynamicObject;
        //            //    var auxId = auxPropId == null ? 0 : Convert.ToInt32(auxPropId["Id"]);
        //            //    decimal invQty = GetInvQty(matNumber, maiOrgId, auxId);
        //            //    string upInvQty = string.Format($"/*dialect*/ UPDATE T0 SET F_InvQty={invQty} FROM t_PUR_POOrderEntry T0 WHERE T0.FENTRYID={eId} ");
        //            //    sqlArray.Add(upInvQty);
        //            //    decimal notInQty = GetNotInQty(maiOrgId, matNumber, auxId);
        //            //    string upNotInQty = string.Format($"/*dialect*/ UPDATE T0 SET F_NotInQty={notInQty} FROM t_PUR_POOrderEntry T0 WHERE T0.FENTRYID={eId} ");
        //            //    sqlArray.Add(upNotInQty);
        //            //    decimal mastPrice = GetMastPrice(maiOrgId, matNumber, auxId);
        //            //    string upMastPrice = string.Format($"/*dialect*/ UPDATE T0 SET F_MastPrice={mastPrice} FROM t_PUR_POOrderEntry T0 WHERE T0.FENTRYID={eId} ");
        //            //    sqlArray.Add(upMastPrice);
        //            //    decimal pickQty = GetPickQty(maiOrgId, matNumber, auxId);
        //            //    string upPickQty = string.Format($"/*dialect*/ UPDATE T0 SET F_PickQty={pickQty} FROM t_PUR_POOrderEntry T0 WHERE T0.FENTRYID={eId} ");
        //            //    sqlArray.Add(upPickQty);
        //            //}
        //            //if (sqlArray.Count > 0)
        //            //{
        //            //    DBServiceHelper.ExecuteBatch(this.Context, sqlArray);
        //            //}
        //        }
        //    }
        //}

        private void ReSaveObj(int id, IOperationResult operationResult, int maiOrgId)
        {
            //创建视图
            IBillView billView = CreateBillView.CreateView(this.Context, "PUR_PurchaseOrder");
            ((IBillViewService)billView).LoadData();
            DynamicFormViewPlugInProxy eventProxy = billView.GetService<DynamicFormViewPlugInProxy>();
            eventProxy.FireOnLoad();
            billView.Model.Load(id);
            DynamicObjectCollection rows = billView.Model.DataObject["POOrderEntry"] as DynamicObjectCollection;
            for (int i = 0; i < rows.Count; i++)
            {
                var eId = Convert.ToInt32(rows[i]["Id"]);
                var mat = rows[i]["MaterialId"] as DynamicObject;
                var matNumber = mat["Number"].ToString();
                var auxPropId = rows[i]["AuxPropId"] as DynamicObject;
                var auxId = auxPropId == null ? 0 : Convert.ToInt32(auxPropId["Id"]);

                decimal invQty = GetInvQty(matNumber, maiOrgId, auxId);
                billView.Model.SetValue("F_InvQty", invQty, i);

                decimal notInQty = GetNotInQty(maiOrgId, matNumber, auxId);
                billView.Model.SetValue("F_NotInQty", notInQty, i);

                decimal mastPrice = GetMastPrice(maiOrgId, matNumber, auxId);
                billView.Model.SetValue("F_MastPrice", mastPrice, i);

                decimal pickQty = GetPickQty(maiOrgId, matNumber, auxId);
                billView.Model.SetValue("F_PickQty", pickQty, i);
            }
            //保存单据
            CreateBillView.OnlySaveBill(billView, OperateOption.Create(), this.Context, operationResult);
        }

        private decimal GetPickQty(int maiOrgId, string matNumber, int auxId)
        {
            string nowDate = DateTime.Now.AddDays(-7).ToString("d");
            decimal picQty = GetPicQty(maiOrgId, matNumber, auxId, nowDate);
            decimal retQty = GetRetuQty(maiOrgId, matNumber, auxId, nowDate);
            decimal othQty = GetOthQty(maiOrgId, matNumber, auxId, nowDate);
            decimal spPicQty = GetSpPicQty(maiOrgId, matNumber, auxId, nowDate);
            decimal spRetQty = GetSpRetQty(maiOrgId, matNumber, auxId, nowDate);
            decimal feedQty = GetFeedQty(maiOrgId, matNumber, auxId, nowDate);
            return picQty + spPicQty + feedQty - retQty + othQty - spRetQty;
        }

        private decimal GetFeedQty(int maiOrgId, string matNumber, int auxId, string nowDate)
        {
            //string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}' AND FAUXPROPID={auxId} AND FPrdOrgId={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}'  AND FPrdOrgId={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            var lists = Api.ExecuteBillQuery(this.Context, "PRD_FeedMtrl", "FActualQty", filters, "FActualQty", 2000);
            if (lists.Count > 0)
            {
                var sumQty = lists.Select(x => x[0]).Sum(w => Convert.ToDecimal(w));
                return sumQty;
            }
            return 0;
        }

        private decimal GetSpRetQty(int maiOrgId, string matNumber, int auxId, string nowDate)
        {
            //string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}' AND FAUXPROPID={auxId} AND FPrdOrgId={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}' AND FPrdOrgId={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            var lists = Api.ExecuteBillQuery(this.Context, "SP_ReturnMtrl", "FQty", filters, "FQty", 2000);
            if (lists.Count > 0)
            {
                var sumQty = lists.Select(x => x[0]).Sum(w => Convert.ToDecimal(w));
                return sumQty;
            }
            return 0;
        }

        private decimal GetSpPicQty(int maiOrgId, string matNumber, int auxId, string nowDate)
        {
            //string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}' AND FAUXPROPID={auxId} AND FPrdOrgId={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}'  AND FPrdOrgId={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            var lists = Api.ExecuteBillQuery(this.Context, "SP_PickMtrl", "FActualQty", filters, "FActualQty", 2000);
            if (lists.Count > 0)
            {
                var sumQty = lists.Select(x => x[0]).Sum(w => Convert.ToDecimal(w));
                return sumQty;
            }
            return 0;
        }

        private decimal GetOthQty(int maiOrgId, string matNumber, int auxId, string nowDate)
        {
            //string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}' AND FAUXPROPID={auxId} AND FSTOCKORGID={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}'  AND FSTOCKORGID={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            var lists = Api.ExecuteBillQuery(this.Context, "STK_MisDelivery", "FQty", filters, "FQty", 2000);
            if (lists.Count > 0)
            {
                var sumQty = lists.Select(x => x[0]).Sum(w => Convert.ToDecimal(w));
                return sumQty;
            }
            return 0;
        }

        private decimal GetRetuQty(int maiOrgId, string matNumber, int auxId, string nowDate)
        {
            //string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}' AND FAUXPROPID={auxId} AND FPRDORGID={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}'  AND FPRDORGID={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            var lists = Api.ExecuteBillQuery(this.Context, "PRD_ReturnMtrl", "FQty", filters, "FQty", 2000);
            if (lists.Count > 0)
            {
                var sumQty = lists.Select(x => x[0]).Sum(w => Convert.ToDecimal(w));
                return sumQty;
            }
            return 0;
        }

        private decimal GetPicQty(int maiOrgId, string matNumber, int auxId, string nowDate)
        {
            //string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}' AND FAUXPROPID={auxId} AND FPRDORGID={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            string filters = $"FDOCUMENTSTATUS = 'C' AND FDATE>='{nowDate}'  AND FPRDORGID={maiOrgId} AND FMaterialId.FNUMBER='{matNumber}' ";
            var lists = Api.ExecuteBillQuery(this.Context, "PRD_PickMtrl", "FActualQty", filters, "FActualQty", 2000);
            if (lists.Count > 0)
            {
                var sumQty = lists.Select(x => x[0]).Sum(w => Convert.ToDecimal(w));
                return sumQty;
            }
            return 0;
        }

        private decimal GetMastPrice(int maiOrgId, string matNumber, int auxId)
        {
            string nowDate = DateTime.Now.AddDays(-180).ToString("d");
            //string filters = $"FTAXPRICE>0 AND FMaterialId.FNumber='{matNumber}' AND FDocumentStatus='C' AND FPurchaseOrgId={maiOrgId} AND FAuxPropId={auxId} AND FDATE>={nowDate} ";
            string filters = $"FTAXPRICE>0 AND FMaterialId.FNumber='{matNumber}' AND FDocumentStatus='C'  AND FDATE>={nowDate} ";
            var lists = Api.ExecuteBillQuery(this.Context, "PUR_PurchaseOrder", "FTAXPRICE", filters, "FDATE DESC", 2000);
            if (lists.Count > 0)
            {
                return Convert.ToDecimal(lists.FirstOrDefault().FirstOrDefault());
            }
            return 0;
        }

        private decimal GetNotInQty(int maiOrgId, string matNumber, int auxId)
        {
            decimal qty = 0;
            //string filters = $"FRemainStockINQty>0 AND FMaterialId.FNumber='{matNumber}' AND FDocumentStatus='C' AND FCloseStatus='A' FCancelStatus='A' AND FMRPCloseStatus='A'  AND FPurchaseOrgId={maiOrgId} AND FAuxPropId={auxId} ";
            //string filters = $"FRemainStockINQty>0 AND FMaterialId.FNumber='{matNumber}' AND FDocumentStatus='C' AND FCloseStatus='A' FCancelStatus='A' AND FMRPCloseStatus='A'  AND FPurchaseOrgId={maiOrgId}  ";
            //var lists = Api.ExecuteBillQuery(this.Context, "PUR_PurchaseOrder", "FRemainStockINQty", filters, "FRemainStockINQty", 2000);
            //if (lists.Count > 0)
            //{
            //    var sumQty = lists.Select(x => x[0]).Sum(w => Convert.ToDecimal(w));
            //    return sumQty;
            //}
            string sql = string.Format($@"select t3.FRemainStockINQty from t_PUR_POOrder t0
            join t_PUR_POOrderEntry t1 on t1.FID=t0.FID
            join T_BD_MATERIAL t2 on t2.FMATERIALID=t1.FMATERIALID
            join T_PUR_POORDERENTRY_R t3 on t3.FENTRYID=t1.FENTRYID
            where t0.FPURCHASEORGID={maiOrgId} and t2.FNUMBER='{matNumber}'
            and t3.FRemainStockINQty>0 AND t0.FDocumentStatus='C' AND t0.FCloseStatus='A' and FCancelStatus='A' AND FMRPCloseStatus='A'");
            var res = DBServiceHelper.ExecuteDataSet(this.Context, sql).Tables[0];
            if (res.Rows.Count > 0)
            {
                qty = res.Select().Sum(s => Convert.ToDecimal(s[0]));
            }
            return qty;
        }

        private decimal GetInvQty(string matNumber, int maiOrgId, int auxId)
        {
            //string filters = $"FMaterialId.FNumber='{matNumber}'  AND FBASEQTY>0 and FStockOrgId={maiOrgId} AND FAuxPropId={auxId} AND FStockName NOT LIKE '%不良%' AND FStockName NOT LIKE '%废品%'";
            string filters = $"FMaterialId.FNumber='{matNumber}'  AND FBASEQTY>0 and FStockOrgId={maiOrgId}  AND FStockName NOT LIKE '%不良%' AND FStockName NOT LIKE '%废品%'";
            var lists = Api.ExecuteBillQuery(this.Context, "STK_Inventory", "FBASEQTY", filters, "FBASEQTY", 2000);
            if (lists.Count > 0)
            {
                var sumQty = lists.Select(x => x[0]).Sum(w => Convert.ToDecimal(w));
                return sumQty;
            }
            return 0;
        }

        /// <summary>
        /// 加载所有列
        /// </summary>
        /// <param name="e"></param>
        public override void OnPreparePropertys(PreparePropertysEventArgs e)
        {
            base.OnPreparePropertys(e);
            FormMetadata meta = MetaDataServiceHelper.GetFormMetaData(this.Context, this.BusinessInfo.GetForm().Id);
            var fieldKeyList = meta.BusinessInfo.GetBosFields().Select(x => x.Field.Key).ToList();
            for (int i = 0; i < fieldKeyList.Count; i++)
            {
                e.FieldKeys.Add(fieldKeyList[i]);
            }
        }
    }
}
